package server.utils;

import server.main.server_main;
import model.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.Socket;
import java.util.AbstractMap;
import java.util.logging.*;
import java.util.logging.Formatter;

import com.google.gson.Gson;

import java.util.*;

public class MessageForward implements Runnable {
	private Socket conSocket;
    private DataInputStream dataInputStream;
    private DataOutputStream dataOutputStream;
    private int userID;
    private boolean isClose;
    private boolean isFile;
    private static final Logger logger = Logger.getLogger(MessageForward.class.getName());

    public MessageForward(Socket conSocket, DataInputStream input,DataOutputStream output,int userid ) {  
    		this.conSocket = conSocket;
            this.dataInputStream = input;
            this.dataOutputStream = output;
            this.isClose = false;
            this.userID = userid;
            this.isFile = false;
            // 设置日志级别
            logger.setLevel(Level.INFO);
            // 创建一个文件处理器
            try {
            	String path = "." + File.separator + "log" + File.separator + "messageForward.log";
                FileHandler fileHandler = new FileHandler(path);
                fileHandler.setLevel(Level.INFO);

                // 创建一个日志格式化器
                Formatter formatter = new SimpleFormatter();
                fileHandler.setFormatter(formatter);

                // 将处理器添加到日志记录器
                logger.addHandler(fileHandler);
            } catch (IOException e) {
                e.printStackTrace();
            }

            System.out.println("user :"+userID+"成功连接准备消息转发通信");
            logger.info("user :"+userID+"成功连接准备消息转发通信");
    }
    public int getUserID() {
        return this.userID;
    }
    public class Pair<K, V> extends AbstractMap.SimpleEntry<K, V> {
        public Pair(K key, V value) {
            super(key, value);
        }
    }
    private Pair<Integer, String> receive() {
        String msg = "";
        Integer roomID = -1;
        Pair<Integer, String> pair = null;
        Message mes = new Message();
        Gson gson = new Gson();
         
        try {
        	String encryptedMessage = dataInputStream.readUTF();
        	String json = Crypto.decrypt(encryptedMessage);
        	System.out.println("收到一条消息" + json);
        	//logger.info("收到一条消息" + json + "准备进行转发");
            mes = gson.fromJson(json, Message.class);
            
            if(mes.getType() == MsgType.COMMON_MESSAGE) {
            	msg = mes.getText();
            	roomID = mes.getRoomID();
            	pair = new Pair<Integer,String>(roomID, msg);
            	logger.info("收到一条消息" + json + "进行转发");
            } else if(mes.getType() == MsgType.CLOSE_MESSAGE) {
            	server_main.connSocketList.remove(this);
            	logger.info("用户退出聊天室");
                Message mes1 = new Message();
                mes1.setType(MsgType.CONFIRM_CLOSE);
                Gson gson1 = new Gson();
                String json1 = gson1.toJson(mes1);
	        	String encryptedMessage1 = Crypto.encrypt(json1);
	        	dataOutputStream.writeUTF(encryptedMessage1);
            	isClose = true; 	
            	conSocket.close();
            } else if(mes.getType() == MsgType.FILE_MESSAGE) {
            	msg = mes.getText();
            	roomID = mes.getRoomID();
            	pair = new Pair<Integer,String>(roomID, msg);
            	logger.info("收到一条文件消息" + json + "进行转发");
            	isFile = true;
            }
        } catch (Exception e) {
            this.isClose = true;
            System.out.println(e);
            logger.warning("接收信息错误");
            try {
                this.dataInputStream.close();
                this.dataOutputStream.close();
                server_main.connSocketList.remove(this);
                System.out.println(e);
            } catch (IOException ce) {
                System.out.println(ce);
            }
        }
        return pair;
    }
    private void send(String msg) {
        try {
            this.dataOutputStream.writeUTF(msg);
            this.dataOutputStream.flush();
            logger.info("消息转发成功");
        } catch (IOException e) {
            this.isClose = true;
            System.out.println(e);
            try {
                this.dataInputStream.close();
                this.dataOutputStream.close();
                server_main.connSocketList.remove(this);
                System.out.println(e);        
            } catch (IOException ce) {
                System.out.println(ce);
            }
        }
    }
    private void sendFile(String fileName, byte[] fileBytes) {
    	try {
    		dataOutputStream.writeUTF(fileName);
    		dataOutputStream.writeLong(fileBytes.length);
    		dataOutputStream.write(fileBytes, 0, fileBytes.length);
    		System.out.println("文件发送成功");
    		logger.info("文件转发成功");
    	} catch (Exception e) {
			// TODO: handle exception
		}
    }
    private void forward() {
    	System.out.println("user :"+userID+"成功连接准备消息转发通信3");
    	logger.info("user :"+userID+"成功连接准备消息转发通信");
        Pair<Integer, String> pair = this.receive();
        if(!isClose) {
        System.out.println("user :"+userID+"成功收到消息");
        logger.info("user :"+userID+"成功收到消息");
        DAO.RoomDao rommdao = new DAO.RoomDao(server_main.db.con);
        DAO.TotalDao Tdao = new DAO.TotalDao(server_main.db.con);
        String msg = pair.getValue();
        int roomID = pair.getKey();
        List<MessageForward> list  = server_main.connSocketList;
        
        Tdao.insertMessage(roomID, userID, msg);
        Vector<Integer> users =rommdao.getAllUser(roomID);
        Message mes = new Message();
        if(!isFile)
        	mes.setType(MsgType.COMMON_MESSAGE);
        else
        	mes.setType(MsgType.FILE_MESSAGE);
        mes.setRoomID(roomID);
        mes.setUserID(userID);
        mes.setText(msg);
        Gson gson = new Gson();
        String json = gson.toJson(mes);
        String encryptedMessage = "";
        try {
    	encryptedMessage = Crypto.encrypt(json);
        } catch (Exception e) {
			// TODO: handle exception
		}
        System.out.println("mes:"+encryptedMessage);
        System.out.println("users size:"+users.size());
        for(MessageForward l : list) {
        	for(int i = 0;i < users.size();i++) {
        		if(l.userID == this.userID) {
            		continue;
            	}
        		
        		if(l.userID == users.elementAt(i)) {
        			l.send(encryptedMessage);
        			System.out.println("发送给其他用户" + l.userID);
        		}
        	}
        	
        }
        if(isFile) {
        	System.out.println("开出新线程准备接收");
        	isFile = false;
        	// 接收文件
            // 读取文件名和文件内容
        	try {
            String fileName = dataInputStream.readUTF();
            long fileSize = dataInputStream.readLong();
            byte[] fileBytes = new byte[(int) fileSize];
            System.out.println(fileName);
            System.out.println(fileSize);
            this.dataInputStream.readFully(fileBytes, 0, fileBytes.length);
            System.out.println("文件接收成功");
            logger.info("文件：" + fileName + "  " + "文件大小：" + fileSize + "接收成功");

            for(MessageForward l : list) {
            	for(int i = 0;i < users.size();i++) {
            		if(l.userID == this.userID) {
                		continue;
                	}
            		if(l.userID == users.elementAt(i)) {
                		l.sendFile(fileName, fileBytes);
                		System.out.println("将文件发送给其他用户" + l.userID);
            		}
            	}
            	
            }
        	} catch (Exception e) {
				// TODO: handle exception
        		System.out.println(e);
			}
        }
        }
    }
    
    public void run() {
    	System.out.println("user :"+userID+"成功连接准备消息转发通信2");
        while(!this.isClose) {
            this.forward();
        }
    }
    
 
}